package com.r2coding.auth.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import javax.sql.DataSource;
import java.util.concurrent.TimeUnit;

/**
 * @author:98k灬
 * @since:2022/04/08 23:12
 **/
@Configuration
public class TokenConfig {
    // 采用redis管理token
    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    // token在redis中保存的时长  2天
    private static final long KEEP_ALIVE_TIME = 24 * 60 * 60 * 2;

    @Autowired
    JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    StringRedisTemplate redisTemplate;

    // 采用jdbc管理token
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    @Bean
    public TokenStore tokenStore() {
        // redis管理令牌
        // return new RedisTokenStore(redisConnectionFactory);
        // JDBC管理令牌
        // return new JdbcTokenStore(dataSource());
        // 采用JWT管理令牌
        return new JwtTokenStore(jwtAccessTokenConverter) {
            @Override
            public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
                // 将jwt中的唯一标识jti作为redis的key value就是token
                if (token.getAdditionalInformation().containsKey("jti")) {
                    String jti = token.getAdditionalInformation().get("jti").toString();
                    // 存储到redis
                    redisTemplate.opsForValue().set(jti, token.getValue(), KEEP_ALIVE_TIME, TimeUnit.SECONDS);
                }
            }

            @Override
            public void removeAccessToken(OAuth2AccessToken token) {
                if (token.getAdditionalInformation().containsKey("jti")) {
                    String jti = token.getAdditionalInformation().get("jti").toString();
                    redisTemplate.delete(jti);
                }
                super.removeAccessToken(token);
            }
        };
    }
}
